#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
//#include <sys/un.h>
#include <pthread.h>
#include "serial.h"
#define SERVERPORT    8888
#define BACKLOG         10

int  sockfd,newfd;
void *read_socket();
void *write_socket();
char recv_buf[40]={0};
char send_buf[40]={0};
pthread_mutex_t mymutexsend = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mymutexrecv= PTHREAD_MUTEX_INITIALIZER;

int cmosnumber=-1;


int main(int argc,char **argv)
{
    int ret;
    int sin_size;
    pthread_t read_tid,write_tid;
    struct sockaddr_in server_addr;
    struct sockaddr_in remote_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(SERVERPORT);
    server_addr.sin_addr.s_addr=INADDR_ANY;
    bzero(&(server_addr.sin_zero),8);
    //strcpy(server_addr.sun_path,"/lch/test/server.socket");
    cmosnumber=tty_init();
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if (sockfd<0)
    {
        printf("Create Socket EOOR！\n");
        close(cmosnumber);
        exit(1);
    }
    printf("socket建立成功。！\n");
    ret=bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr_in));
    if (ret<0)
    {
        printf("调用bind函数绑定套接字与地址出错！\n");
        close(cmosnumber);
        exit(2);
    }
    printf("blind成功！\n");
    ret=listen(sockfd,BACKLOG);
    if(ret<0)
    {
        printf("listen失败！\n");
        close(cmosnumber);
        exit(3);
    }

    printf("调用listen函数成功\n");
    newfd=accept(sockfd,(struct sockaddr_in *)&remote_addr,&sin_size);
    if (newfd<0)
    {
        printf("调用accept函数出错\n");
        close(cmosnumber);
        exit(4);
    }
    printf("调用accept函数成功，服务器与客户端建立连接成功！\n");
    
    pthread_create(&read_tid,NULL,read_socket,NULL);
    pthread_create(&write_tid,NULL,write_socket,NULL);
    
    while(1)
    {
        sleep(10000);
    }
}

void *read_socket()
{   
    int recv_num=0;
    int res=-1;
    while (1)
    {
        
        pthread_mutex_lock(&mymutexsend);
        recv_num=recv(newfd,recv_buf,1,0);
        if (recv_num<0)
        {
            printf("服务器端：调用recv接收失败！\n");
            pthread_mutex_unlock(&mymutexsend);
        }
        else if(recv_num>0)
        {
            res=write(cmosnumber,recv_buf,1);
            printf("Com1 send :%d\n",res);
            pthread_mutex_unlock(&mymutexsend);
            printf("server call recv success ,this time send %d bytes，content\"%s\"\n",recv_num,recv_buf);
        }
        else/*收到数据为0，表明服务器与客户端的连接已经中断*/
        {
            printf("服务器端：与客户端的连接已中断\n");
            pthread_mutex_unlock(&mymutexsend);
            newfd=accept(sockfd,NULL,NULL);/*当客户端退出后，再次开始接收客户端的连接*/
        }
        sleep(1);
    }
}

/****************** 向socket发送数据 ********************/
void *write_socket()
{
    int send_num=0;
    char send_buf[]="I'm the data from SERVER!";
    int res =-1;
    while(1)
    {
        pthread_mutex_lock(&mymutexrecv);
        res=read(cmosnumber,send_buf,1);
        send_buf[res]=0;
        send_num=send(newfd,send_buf,strlen(send_buf),0);
        if (send_num<0)
        {
            printf("服务器端：调用send函数失败！");
            pthread_mutex_unlock(&mymutexrecv);
        }
        else
        {
            printf("服务器端：调用send函数成功，本次发送%d个字节，内容为：\"%s\"。\n",send_num,send_buf);
            pthread_mutex_unlock(&mymutexrecv);
        }
        sleep(2);
    }    
}






int tty_init()
{

        int fd;
    struct termios TtyAttr;
    struct termios BackupTtyAttr;

    int DeviceSpeed = B9600;
    int TtySpeed = B9600;
    int ByteBits = CS8;
    const char *DeviceName = "/dev/ttySAC1";
    opterr = 0;
 
    fd = open(DeviceName, O_RDWR, 0);
    if (fd < 0)
    {
	printf("Unable to open device\n");
        exit(-1);
    }
    //if (fcntl(CommFd, F_SETFL, O_NONBLOCK) < 0)
     //	Error("Unable set to NONBLOCK mode");
    printf("**success**fd**%d**%d,**%d\n",fd,fd,fd);

    memset(&TtyAttr, 0, sizeof(struct termios));
    TtyAttr.c_iflag = IGNPAR;
    TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD | CLOCAL;
    TtyAttr.c_cc[VMIN] = 1;

    if (tcsetattr(fd, TCSANOW, &TtyAttr) < 0)
    {
        printf("Unable to set comm port\n");
        exit(-2);
    }
    return fd;
}



int ttys_init()
{
        int fd=-1;
	fd = open(COM2, O_RDWR ); //| O_NONBLOCK);//
        printf("FD==================%d*****************%d*********************%d",fd,fd,fd);
	if (fd <0) {
             printf("**error****fd****%d*****%d,**%d\n",fd,fd,fd);
	     perror(COM2);
	     exit(-1);
               
  	}
	printf("**success**fd**%d**%d,**%d\n",fd,fd,fd);
//  	tcgetattr(0,&oldstdtio);
  	tcgetattr(fd,&oldtio); /* save current modem settings */
//  	tcgetattr(fd,&newstdtio); /* get working stdtio */
	bzero(&newtio, sizeof(newtio)); 



	newtio.c_cflag = baud | /*CRTSCTS |*/ CS8 /*| CLOCAL | CREAD */;
	newtio.c_iflag = IGNPAR | ICRNL; 
	newtio.c_oflag = 0; 
	newtio.c_lflag = ICANON;

	 newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */  
	 newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */ 
	 newtio.c_cc[VERASE]   = 0;     /* del */ 
	 newtio.c_cc[VKILL]    = 0;     /* @ */ 
	 newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */ 
	 newtio.c_cc[VTIME]    = 0;     /* 不使用分割字元组的计时器 */ 
	 newtio.c_cc[VMIN]     = 1;     /* 在读取到 1 个字元前先停止 */ 
	 newtio.c_cc[VSWTC]    = 0;     /* '\0' */ 
	 newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */  
	 newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */ 
	 newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */ 
	 newtio.c_cc[VEOL]     = 0;     /* '\0' */ 
	 newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */ 
	 newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */ 
	 newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */ 
	 newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */ 
	 newtio.c_cc[VEOL2]    = 0;     /* '\0' */ 


//	newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
//	newtio.c_oflag  &= ~OPOST;   /*Output*/
 	tcflush(fd, TCIFLUSH);
	tcsetattr(fd,TCSANOW,&newtio);/*set attrib	  */

#if 0	
	newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;/*ctrol flag*/
	newtio.c_iflag = IGNPAR; /*input flag*/
	newtio.c_oflag = 0;		/*output flag*/
 	newtio.c_lflag = 0;
 	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
//#else	
	newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;/*ctrol flag*/
//	newtio.c_iflag = IGNPAR; /*input flag*/
	newtio.c_iflag &= ~(ICRNL|IGNCR | INLCR |IGNBRK |BRKINT ); //input flag
	newtio.c_oflag &= ~OPOST;		/*output flag*/
 	newtio.c_lflag = ECHO |NOFLSH;
 	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
#endif

	return fd;
}
